home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Browsers, Managers & Extensions / Mozilla Weave 0.2.7 / latest-weave.xpi / chrome / sync.jar / content / sync.js < prev    next >
Text File  |  2008-07-21  |  17KB  |  498 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Bookmarks Sync.
  15.  *
  16.  * The Initial Developer of the Original Code is Mozilla.
  17.  * Portions created by the Initial Developer are Copyright (C) 2007
  18.  * the Initial Developer. All Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  *  Dan Mills <thunder@mozilla.com>
  22.  *  Chris Beard <cbeard@mozilla.com>
  23.  *  Dan Mosedale <dmose@mozilla.org>
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the MPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the MPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. var Cc = Components.classes;
  40. var Ci = Components.interfaces;
  41.  
  42. function Sync() {
  43.   this._log = Log4Moz.Service.getLogger("Chrome.Window");
  44.  
  45.   this._log.info("Initializing Weave UI");
  46.  
  47.   this._os.addObserver(this, "weave:service:login:start", false);
  48.   this._os.addObserver(this, "weave:service:login:success", false);
  49.   this._os.addObserver(this, "weave:service:login:error", false);
  50.   this._os.addObserver(this, "weave:service:logout:success", false);
  51.   this._os.addObserver(this, "weave:service:sync:start", false);
  52.   this._os.addObserver(this, "weave:service:sync:success", false);
  53.   this._os.addObserver(this, "weave:service:sync:error", false);
  54.   this._os.addObserver(this, "weave:notification:added", false);
  55.   this._os.addObserver(this, "weave:notification:removed", false);
  56.  
  57.   if (!Weave.Crypto.checkModule()) {
  58.     setTimeout(function() {
  59.       alert("There has been a problem loading the Weave crypto component.\n" +
  60.             "Weave will not work correctly, apologies for the inconvenence.")
  61.     }, 500);
  62.     return;
  63.   }
  64.  
  65.   if (Weave.Utils.prefs.getBoolPref("ui.syncnow"))
  66.     document.getElementById("sync-syncnowitem").setAttribute("hidden", false);
  67.  
  68.   if (Weave.Utils.prefs.getCharPref("lastversion") == "firstrun") {
  69.     let url = "http://services.mozilla.com/firstrun/?version=" +
  70.       Weave.WEAVE_VERSION;
  71.     setTimeout(function() { window.openUILinkIn(url, "tab"); }, 500);
  72.  
  73.   } else if (Weave.Utils.prefs.getCharPref("lastversion") != Weave.WEAVE_VERSION) {
  74.     let url = "http://services.mozilla.com/updated/?version=" +
  75.       Weave.WEAVE_VERSION;
  76.     setTimeout(function() { window.openUILinkIn(url, "tab"); }, 500);
  77.   }
  78.  
  79.   // FIXME: hack
  80.   if (Weave.Utils.prefs.getCharPref("lastversion") == "0.1.30" ||
  81.       Weave.Utils.prefs.getCharPref("lastversion") == "0.1.32" ||
  82.       Weave.Utils.prefs.getCharPref("lastversion") == "0.1.33" ||
  83.       Weave.Utils.prefs.getCharPref("lastversion") == "0.1.34") {
  84.     this._prefSvc.setCharPref("extensions.weave.username", "nobody");
  85.     setTimeout(function() {
  86.       alert("Due to server changes you need to re-run the setup wizard.\n" +
  87.             "If this is the first computer you upgrade to version " +
  88.             Weave.WEAVE_VERSION + ", you MUST create a new account.");
  89.     }, 500);
  90.   }
  91.  
  92.   Weave.Utils.prefs.setCharPref("lastversion", Weave.WEAVE_VERSION);
  93.  
  94.   let username = this._prefSvc.getCharPref("extensions.weave.username");
  95.   if (!username || username == 'nobody') {
  96.       setTimeout(function() { gSync.doOpenSetupWizard(); }, 500);
  97.   }
  98.  
  99.   // TODO: This is a fix for the general case of bug 436936.  It will
  100.   // not support marginal cases such as when a new browser window is
  101.   // opened in the middle of signing-in or syncing.
  102.   if (Weave.Service.isInitialized)
  103.     this._onLogin();
  104.  
  105.   Weave.Service.onWindowOpened();
  106. }
  107. Sync.prototype = {
  108.   get _isTopBrowserWindow() {
  109.     // TODO: This code is mostly just a workaround that ensures that only one
  110.     // browser window ever performs any actions that are meant to only
  111.     // be performed once in response to a weave event.  Ideally, such code
  112.     // should not be handled by browser windows, but instead by e.g. actual
  113.     // singleton services.
  114.     var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  115.                        .getService(Components.interfaces.nsIWindowMediator);
  116.     var win = wm.getMostRecentWindow("navigator:browser");
  117.     return (win == window);
  118.   },
  119.  
  120.   __os: null,
  121.   get _os() {
  122.     if (!this.__os)
  123.       this.__os = Cc["@mozilla.org/observer-service;1"]
  124.         .getService(Ci.nsIObserverService);
  125.     return this.__os;
  126.   },
  127.  
  128.   __prefSvc: null,
  129.   get _prefSvc() {
  130.     if (!this.__prefSvc) {
  131.       this.__prefSvc = Cc["@mozilla.org/preferences-service;1"]
  132.         .getService(Ci.nsIPrefBranch);
  133.       this.__prefSvc.QueryInterface(Ci.nsIPrefBranch2);
  134.     }
  135.     return this.__prefSvc;
  136.   },
  137.  
  138.   _getPref: function(prefName, defaultValue) {
  139.     let prefSvc = this._prefSvc;
  140.  
  141.     try {
  142.       switch (prefSvc.getPrefType(prefName)) {
  143.         case Ci.nsIPrefBranch.PREF_STRING:
  144.           return prefSvc.getCharPref(prefName);
  145.         case Ci.nsIPrefBranch.PREF_INT:
  146.           return prefSvc.getIntPref(prefName);
  147.         case Ci.nsIPrefBranch.PREF_BOOL:
  148.           return prefSvc.getBoolPref(prefName);
  149.       }
  150.     }
  151.     catch (ex) {}
  152.  
  153.     return defaultValue;
  154.   },
  155.  
  156.   get _baseURL() {
  157.     return this._getPref("extensions.weave.serverURL");
  158.   },
  159.  
  160.   get _locale() {
  161.     switch (this._getPref("general.useragent.locale", "en-US")) {
  162.       case 'ja':
  163.       case 'ja-JP-mac':
  164.         return "ja";
  165.     }
  166.  
  167.     return "en-US";
  168.   },
  169.  
  170.   get _stringBundle() {
  171.     let stringBundle = document.getElementById("weaveStringBundle");
  172.     this.__defineGetter__("_stringBundle",
  173.                           function() { return stringBundle; });
  174.     return this._stringBundle;
  175.   },
  176.  
  177.   get _windowType() {
  178.     let wm = Cc["@mozilla.org/appshell/window-mediator;1"].
  179.              getService(Ci.nsIWindowMediator);
  180.     let win = wm.getMostRecentWindow("");
  181.     return win.document.documentElement.getAttribute("windowtype");
  182.   },
  183.  
  184.   _openWindow: function Sync__openWindow(type, uri, options) {
  185.     let wm = Cc["@mozilla.org/appshell/window-mediator;1"].
  186.       getService(Ci.nsIWindowMediator);
  187.     let window = wm.getMostRecentWindow(type);
  188.     if (window)
  189.       window.focus();
  190.      else {
  191.        var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
  192.          getService(Ci.nsIWindowWatcher);
  193.        if (!options)
  194.          options = 'chrome,centerscreen,dialog,modal,resizable=yes';
  195.        ww.activeWindow.openDialog(uri, '', options, null);
  196.      }
  197.   },
  198.  
  199.   _setStatus: function Sync__setStatus(status) {
  200.     document.getElementById("sync-menu-button").setAttribute("status", status);
  201.  
  202.     let label;
  203.     if (status == "offline")
  204.       label = this._stringBundle.getString("status.offline");
  205.     else {
  206.       let username = this._prefSvc.getCharPref("extensions.weave.username");
  207.       if (!username || username == 'nobody@mozilla.com') {
  208.         this._log.error("status is " + status + ", but username not set");
  209.         // Fall back to a generic string.
  210.         label = this._stringBundle.getString("status." + status);
  211.       }
  212.       else
  213.         label = username;
  214.     }
  215.     document.getElementById("sync-menu-status").setAttribute("value", label);
  216.   },
  217.  
  218.   _onLoginStart: function Sync__onLoginStart() {
  219.     this._log.info("Logging in...");
  220.     this._log.info("User string: " + navigator.userAgent);
  221.     this._log.info("Weave version: " + Weave.WEAVE_VERSION);
  222.     this._setStatus("active");
  223.   },
  224.  
  225.   _onLoginError: function Sync__onLoginError() {
  226.     this._setStatus("offline");
  227.  
  228.     let title = this._stringBundle.getString("error.login.title");
  229.     let description =
  230.     this._stringBundle.getString("error.login.description");
  231.     let notification =
  232.     new Weave.Notification(title,
  233.                            description,
  234.                            null,
  235.                            Weave.Notifications.PRIORITY_WARNING);
  236.     Weave.Notifications.add(notification);
  237.   },
  238.  
  239.   _onLogin: function Sync__onLogin() {
  240.     this._log.info("Login successful");
  241.     this._setStatus("idle");
  242.  
  243.     this._userLogin = false;
  244.  
  245.     let loginitem = document.getElementById("sync-loginitem");
  246.     let logoutitem = document.getElementById("sync-logoutitem");
  247.     if(loginitem && logoutitem) {
  248.       loginitem.setAttribute("hidden", "true");
  249.       logoutitem.setAttribute("hidden", "false");
  250.     }
  251.  
  252.     let syncnowitem = document.getElementById("sync-syncnowitem");
  253.     if (syncnowitem)
  254.       syncnowitem.setAttribute("disabled", "false");
  255.   },
  256.  
  257.   _onLogout: function Sync__onLogout(status) {
  258.     if (status)
  259.       this._setStatus("offline");
  260.     else {
  261.       this._setStatus("idle");
  262.       let title = this._stringBundle.getString("error.logout.title");
  263.       let description =
  264.         this._stringBundle.getString("error.logout.description");
  265.       let notification =
  266.         new Weave.Notification(title,
  267.                                description,
  268.                                null,
  269.                                Weave.Notifications.PRIORITY_WARNING);
  270.       Weave.Notifications.add(notification);
  271.     }
  272.  
  273.     let loginitem = document.getElementById("sync-loginitem");
  274.     let logoutitem = document.getElementById("sync-logoutitem");
  275.     if(loginitem && logoutitem) {
  276.       loginitem.setAttribute("hidden", "false");
  277.       logoutitem.setAttribute("hidden", "true");
  278.     }
  279.  
  280.     let syncnowitem = document.getElementById("sync-syncnowitem");
  281.     if (syncnowitem)
  282.       syncnowitem.setAttribute("disabled", "true");
  283.   },
  284.  
  285.   _onSyncStart: function Sync_onSyncStart() {
  286.     this._setStatus("active");
  287.  
  288.     let syncitem = document.getElementById("sync-syncnowitem");
  289.     if(syncitem)
  290.       syncitem.setAttribute("disabled", "true");
  291.  
  292.     let logoutitem = document.getElementById("sync-logoutitem");
  293.     if(logoutitem)
  294.       logoutitem.setAttribute("disabled", "true");
  295.   },
  296.  
  297.   _onSyncEnd: function Sync_onSyncEnd(status) {
  298.     this._setStatus("idle");
  299.  
  300.     if (!status &&
  301.         Weave.FaultTolerance.Service.lastException != "Could not acquire lock") {
  302.       let title = this._stringBundle.getString("error.sync.title");
  303.       let description = this._stringBundle.getString("error.sync.description");
  304.       let tryAgainButton =
  305.         new Weave.NotificationButton(
  306.           this._stringBundle.getString("error.sync.tryAgainButton.label"),
  307.           this._stringBundle.getString("error.sync.tryAgainButton.accesskey"),
  308.           function() { gSync.doSync(); return true; }
  309.         );
  310.       let notification =
  311.         new Weave.Notification(
  312.           title,
  313.           description,
  314.           null,
  315.           Weave.Notifications.PRIORITY_WARNING,
  316.           [tryAgainButton]
  317.         );
  318.       Weave.Notifications.add(notification);
  319.     }
  320.  
  321.     let syncitem = document.getElementById("sync-syncnowitem");
  322.     if (syncitem)
  323.       syncitem.setAttribute("disabled", "false");
  324.  
  325.     let logoutitem = document.getElementById("sync-logoutitem");
  326.     if(logoutitem)
  327.       logoutitem.setAttribute("disabled", "false");
  328.  
  329.     if (this._isTopBrowserWindow)
  330.       this._prefSvc.setCharPref("extensions.weave.lastsync",
  331.                                 new Date().getTime());
  332.     this._updateLastSyncItem();
  333.   },
  334.  
  335.   shutDown: function Sync_shutDown(event) {
  336.     this._log.info("Sync window closed");
  337.  
  338.     this._os.removeObserver(this, "weave:service:login:start");
  339.     this._os.removeObserver(this, "weave:service:login:success");
  340.     this._os.removeObserver(this, "weave:service:login:error");
  341.     this._os.removeObserver(this, "weave:service:logout:success");
  342.     this._os.removeObserver(this, "weave:service:sync:start");
  343.     this._os.removeObserver(this, "weave:service:sync:success");
  344.     this._os.removeObserver(this, "weave:service:sync:error");
  345.     this._os.removeObserver(this, "weave:notification:added");
  346.     this._os.removeObserver(this, "weave:notification:removed");
  347.   },
  348.  
  349.   doLoginPopup : function Sync_doLoginPopup(event) {
  350.     this._openWindow('Sync:Login', 'chrome://weave/content/login.xul');
  351.   },
  352.  
  353.   doLogin: function Sync_doLogin(event) {
  354.     if (Weave.Service.isInitialized)
  355.       return; // already logged in
  356.  
  357.     let username = this._prefSvc.getCharPref("extensions.weave.username");
  358.  
  359.     if (!username || username == 'nobody') {
  360.       this.doOpenSetupWizard();
  361.       return;
  362.     }
  363.  
  364.     this.doLoginPopup();
  365.   },
  366.  
  367.   doOpenSetupWizard : function Sync_doOpenSetupWizard(event) {
  368.       window.openDialog('chrome://weave/content/wizard.xul', '',
  369.         'chrome,centerscreen,dialog,resizable=yes', null);
  370.   },
  371.  
  372.   doLogout: function Sync_doLogout(event) {
  373.     Weave.Service.logout();
  374.   },
  375.  
  376.   doSync: function Sync_doSync(event) {
  377.     this._openWindow('Sync:Status', 'chrome://weave/content/status.xul');
  378.   },
  379.  
  380.   doShare: function Sync_doShare(event) {
  381.     this._openWindow('Sync:Share', 'chrome://weave/content/share.xul');
  382.   },
  383.  
  384.   doCancelSync: function Sync_doCancelSync(event) {
  385.     this._log.error("cancel sync unimplemented");
  386.   },
  387.  
  388.   doOpenPrefs: function Sync_doOpenPrefs(event) {
  389.     try {  
  390.       openPreferences("sync-prefpane");  // firefox
  391.     } catch (ex) {
  392.       openOptionsDialog("sync-prefpane");  // thunderbird
  393.     }
  394.   },
  395.  
  396.   onOpenPrefs : function Sync_onOpenPrefs(event) {
  397.     // XXX called when prefpane opens, setup password and login states
  398.   },
  399.  
  400.   doOpenActivityLog: function Sync_doOpenActivityLog(event) {
  401.     this._openWindow('Weave:Log', 'chrome://weave/content/log.xul',
  402.                      'chrome, centerscreen, dialog, resizable=yes');
  403.   },
  404.  
  405.   doPopup: function Sync_doPopup(event) {
  406.     this._updateLastSyncItem();
  407.   },
  408.   
  409.   _onNotificationAdded: function Sync__onNotificationAdded() {
  410.     document.getElementById("sync-notifications-button").hidden = false;
  411.   },
  412.  
  413.   _onNotificationRemoved: function Sync__onNotificationRemoved() {
  414.     if (Weave.Notifications.notifications.length == 0)
  415.       document.getElementById("sync-notifications-button").hidden = true;
  416.   },
  417.  
  418.   _updateLastSyncItem: function Sync__updateLastSyncItem() {
  419.     let lastSync = this._prefSvc.getCharPref("extensions.weave.lastsync");
  420.     if (!lastSync)
  421.       return;
  422.  
  423.     let lastSyncItem = document.getElementById("sync-lastsyncitem");
  424.     if (!lastSyncItem)
  425.       return;
  426.  
  427.     let lastSyncDate = new Date(parseInt(lastSync)).toLocaleString();
  428.     let lastSyncLabel =
  429.       this._stringBundle.getFormattedString("lastSync.label", [lastSyncDate]);
  430.     lastSyncItem.setAttribute("label", lastSyncLabel);
  431.     lastSyncItem.setAttribute("hidden", "false");
  432.   },
  433.  
  434.   onMenuPopupHiding: function Sync_onMenuPopupHiding() {
  435.     var menuPopup = document.getElementById('sync-menu-popup');
  436.     var menu = document.getElementById('sync-menu');
  437.  
  438.     // If the menu popup isn't on the Tools > Sync menu, then move the popup
  439.     // back onto that menu so the popup appears when the user selects the menu.
  440.     // We'll move the popup back to the menu button when the user clicks on
  441.     // the menu button.
  442.     if (menuPopup.parentNode != menu)
  443.       menu.appendChild(menuPopup);
  444.   },
  445.  
  446.   onMenuButtonMouseDown: function Sync_onMenuButtonMouseDown() {
  447.     var menuPopup = document.getElementById('sync-menu-popup');
  448.     var menuButton = document.getElementById("sync-menu-button");
  449.  
  450.     // If the menu popup isn't on the menu button, then move the popup onto
  451.     // the button so the popup appears when the user clicks the button.  We'll
  452.     // move the popup back to the Tools > Sync menu when the popup hides.
  453.     if (menuPopup.parentNode != menuButton)
  454.       menuButton.appendChild(menuPopup);
  455.   },
  456.  
  457.   // nsIObserver
  458.   observe: function(subject, topic, data) {
  459.     switch(topic) {
  460.     case "weave:service:login:start":
  461.       this._onLoginStart();
  462.       break;
  463.     case "weave:service:login:success":
  464.       this._onLogin();
  465.       break;
  466.     case "weave:service:login:error":
  467.       this._onLoginError();
  468.       break;
  469.     case "weave:service:logout:success":
  470.       this._onLogout(true);
  471.       break;
  472.     case "weave:service:sync:start":
  473.       this._onSyncStart();
  474.       break;
  475.     case "weave:service:sync:success":
  476.       this._onSyncEnd(true);
  477.       break;
  478.     case "weave:service:sync:error":
  479.       this._onSyncEnd(false);
  480.       break;
  481.     case "weave:notification:added":
  482.       this._onNotificationAdded();
  483.       break;
  484.     case "weave:notification:removed":
  485.       this._onNotificationRemoved();
  486.       break;
  487.     default:
  488.       this._log.warn("Unknown observer notification topic: " + topic);
  489.       break;
  490.     }
  491.   }
  492. };
  493.  
  494. let gSync;
  495.  
  496. window.addEventListener("load", function(e) { gSync = new Sync(); }, false);
  497. window.addEventListener("unload", function(e) { gSync.shutDown(e); }, false);
  498.